home *** CD-ROM | disk | FTP | other *** search
- /* HoWSample.c - Help on Wheels sample application */
-
- /* to compile: BuildProgram HoWS */
-
- /* - - - - - - - - - - - an AWOL Software Production - - - - - - - - - - - */
- /* - - - - - - - - - - - - - (c) 1994 Ross Brown - - - - - - - - - - - - - */
- /* - - - - - - - - - Email: ab026@freenet.carleton.ca - - - - - - - - - */
-
- /* includes */
-
- #define SystemSevenOrLater 1
- #include <Aliases.h>
- #include <AppleEvents.h>
- #include <Balloons.h>
- #include <Desk.h>
- #include <Dialogs.h>
- #include <Errors.h>
- #include <Events.h>
- #include <Files.h>
- #include <Folders.h>
- #include <Fonts.h>
- #include <GestaltEqu.h>
- #include <Icons.h> /* new in System 7, extended beyond that released for MPW 3.2 */
- #include <Language.h>
- #include <Menus.h>
- #include <OSEvents.h>
- #include <OSUtils.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <SegLoad.h>
- #include <Script.h>
- #include <Sound.h>
- #include <SysEqu.h>
- #include <ToolUtils.h>
- #include <Traps.h>
- #include <Types.h>
- #include <Windows.h>
-
- /* Change this to reflect the location of your copy of HoWLib.h. */
- #include "::HoWLib.h"
-
- #include "HoWSample.h"
-
- /* application preferences */
-
- /* application globals */
-
- #define sleepTicks 15
- Boolean done = false;
-
- /* Where are the application file and the preferences file? */
- short applicationFileRefNum;
- short preferencesFileRefNum;
- short preferencesFolderVRefNum;
- Boolean preferencesFileUnwritable;
-
- /* What is the help tag number of the current topic? */
- short topicTag;
-
- /* What is the Command-key equivalent of the Help key? */
- char helpCommandChar;
-
- /* How many System-defined items are there in the Help menu? */
- short systemHelpItemCount;
-
- /* System stuff */
-
- SysEnvRec mac;
-
- /* as documented in Technical Note 304 */
- pascal OSErr SetDialogDefaultItem( DialogPtr theDialog, short newItem )
- = { 0x303C, 0x0304, 0xAA68 };
- pascal OSErr SetDialogCancelItem( DialogPtr theDialog, short newItem )
- = { 0x303C, 0x0305, 0xAA68 };
- pascal OSErr SetDialogTracksCursor( DialogPtr theDialog, Boolean tracks )
- = { 0x303C, 0x0306, 0xAA68 };
- extern pascal Boolean StdFilterProc( DialogPtr theDialog, EventRecord *theEvent, short *itemHit );
-
- Boolean wneIsImplemented; /* Is _WaitNextEvent implemented? */
- Boolean inForeground; /* Is this application in the foreground under MultiFinder? */
-
- Boolean helpMgrPresent;
- Boolean appleEventsPresent;
- Boolean launchControl;
- Boolean findFolderPresent;
- Boolean aliasMgrPresent;
- Boolean standardFile58;
- Boolean hasFSSpecCalls;
- Boolean helpServerPresent;
-
- /* forward function declarations */
-
- void InfoAlert( const char *string );
- void WarningAlert( const char *string );
- void ErrorAlert( const char *string, long code );
-
- char *GetMessage( short messageID, char *message );
-
- void WarningMessage( short warningID );
- void ErrorMessage( short errorID, long code );
-
- char *GetPreloadString( short stringID, char *string );
-
- void DoUpdate( WindowPtr window );
-
- /* utilities */
-
- #pragma segment Main
- void DisplayHelp( short tag, Boolean casual )
- {
- OSErr osErr = HoWDisplay( tag, casual );
-
- if( !casual )
- {
- switch( osErr )
- {
- case noErr:
- case userCanceledErr:
- break;
- case clientNotRegisteredErr:
- ErrorMessage( iHelpNotAvailable, 0 );
- break;
- default:
- ErrorMessage( iCantDisplayHelp, osErr );
- break;
- }
- }
-
- UnloadSeg( (Ptr) HoWDisplay );
-
- }
-
- #pragma segment Initialize
- Boolean TrapAvailable( short tNumber, TrapType tType )
- {
-
- /* Check and see if the trap exists. On 64K ROM machines, tType will be ignored. */
- return NGetTrapAddress( tNumber, tType ) != GetTrapAddress( _Unimplemented );
-
- }
-
- #pragma segment Main
- void AdjustMenus( Boolean option )
- {
- #pragma unused( option )
-
- }
-
- #pragma segment Main
- Boolean IsAppWindow( WindowPtr window )
- {
- short windowKind;
-
- if( window == nil )
- return false;
- else
- {
- /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
- windowKind = ( (WindowPeek) window )->windowKind;
- return ( windowKind >= userKind ) || ( windowKind == dialogKind );
- }
- }
-
- #pragma segment Main
- Boolean IsVolumeLocked( short vRefNum )
- {
- HParamBlockRec pb;
-
- pb.volumeParam.ioCompletion = nil;
- pb.volumeParam.ioNamePtr = nil;
- pb.volumeParam.ioVRefNum = vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- return PBHGetVInfoSync( &pb ) == noErr && ( pb.volumeParam.ioVAtrb & 0x8080 );
-
- }
-
- /* dialog utilities */
-
- #pragma segment Dialogs
- short GetDialogTopicTag( DialogPtr dialog, Point *mousePtr )
- {
- GrafPtr savePort;
- short item;
- short dialogTopicTag = topicTag;
-
- GetPort( &savePort );
- SetPort( dialog );
- GlobalToLocal( mousePtr );
- SetPort( savePort );
-
- /* You should set topicTag to a base value before calling ModalDialog or any other function */
- /* which supports a modal dialog filter, such as CustomGetFile or CustomPutFile. */
- /* Define a tag in your help document with that value which describes the dialog generally. */
- /* For each interesting item in the dialog, define a tag with value equal to the base value */
- /* plus the dialog item number. GeneralModalDialogFilter will then handle both casual help */
- /* displays (by clicking) and non-casual help displays (by pressing help or Command-Period) */
- /* on a per-item basis, with the help of this function. */
- item = 1 + findditem( dialog, mousePtr );
- if( item > 0 )
- dialogTopicTag += item;
-
- return dialogTopicTag;
-
- }
-
- #pragma segment Dialogs
- pascal Boolean GeneralModalDialogFilter( DialogPtr dialog, EventRecord *theEvent, short *itemHit )
- {
-
- switch( theEvent->what )
- {
-
- case updateEvt:
- if( (DialogPtr) theEvent->message != dialog )
- {
- if( IsDialogEvent( theEvent ) )
- { /* Handle update event in dialog behind this one. */
- DialogPtr otherDialog;
- short otherItemHit;
- return DialogSelect( theEvent, &otherDialog, &otherItemHit );
- }
- else
- { /* Handle update event in window behind this one. */
- DoUpdate( (WindowPtr) theEvent->message );
- return true;
- }
- }
- break;
-
- case keyDown:
- {
- unsigned char characterCode = theEvent->message & charCodeMask;
- if( characterCode == helpCommandChar && theEvent->modifiers & cmdKey )
- characterCode = 0x05;
- switch( characterCode )
- {
- case 0x05: /* Help */
- {
- Point mouse = theEvent->where;
- short dialogTopicTag = GetDialogTopicTag( dialog, &mouse );
- WindowPeek windowPeek;
- DialogPtr hiddenDialogs[ 16 ];
- DialogPtr *hiddenDialog = hiddenDialogs;
- /* Hide all visible modal dialogs before displaying help, so that */
- /* switch can occur. */
- for( windowPeek = (WindowPeek) dialog; windowPeek != nil && windowPeek->windowKind == dialogKind && windowPeek->spareFlag < 0; windowPeek = windowPeek->nextWindow )
- {
- if( windowPeek->visible )
- {
- DialogPtr dialogToHide = (DialogPtr) windowPeek;
- ShowHide( dialogToHide, false );
- *hiddenDialog++ = dialogToHide;
- }
- }
- /* This is a non-casual help display. The user directly asked for help. */
- DisplayHelp( dialogTopicTag, false );
- while( hiddenDialog > hiddenDialogs )
- ShowHide( *--hiddenDialog, true );
- }
- *itemHit = 0;
- return true;
- }
- }
- break;
-
- case mouseDown:
- {
- Point mouse = theEvent->where;
- short dialogTopicTag = GetDialogTopicTag( dialog, &mouse );
- /* This is an example of a casual help display. */
- /* A casual display is effective only if the server is started and running in */
- /* the background, with the "follow" option in effect, and already displaying */
- /* this client's help file. */
- DisplayHelp( dialogTopicTag, true );
- }
- break;
-
- }
-
- { /* Let the standard filter procedure handle it. */
- GrafPtr savePort;
- Boolean handled;
- GetPort( &savePort );
- SetPort( dialog );
- handled = StdFilterProc( dialog, theEvent, itemHit );
- SetPort( savePort );
- return handled;
- }
-
- }
-
- /* dialogs */
-
- #pragma segment DoNothing
- void DoNothingDialog( void )
- {
- DialogRecord doNothingDialogRecord;
- DialogPtr doNothingDialog = GetNewDialog( rDoNothingDialog, &doNothingDialogRecord, (WindowPtr) -1 );
- short itemHit;
-
- SetCursor( &qd.arrow );
-
- SetDialogDefaultItem( doNothingDialog, ok );
- SetDialogCancelItem( doNothingDialog, 0 );
- SetDialogTracksCursor( doNothingDialog, false );
-
- ShowWindow( doNothingDialog );
- do
- {
- topicTag = rDoNothingDialog * cTagSpacing;
- ModalDialog( (ModalFilterProcPtr) GeneralModalDialogFilter, &itemHit );
- switch( itemHit )
- {
- case iDNDSqueak:
- SysBeep( 60 );
- break;
- }
- }
- while( itemHit != iDNDSqueak );
-
- CloseDialog( doNothingDialog );
- DisposeHandle( doNothingDialogRecord.items );
-
- }
-
- /* Apple event handlers */
-
- #pragma segment Main
- pascal void HelpEventHandler( short id )
- {
-
- /* This is a sample of what your application can do in response to a Help event. */
- /* Help events are triggered by the user clicking a "hot" hypertext button in the help file. */
- /* The value in "id" is a positive integer. For example, if the user clicks in a part */
- /* of the help file tagged "-23456", and there is no "23456" tag anywhere in the help file, */
- /* this function will be called with id = 23456. If there is a "23456" tag, then the button */
- /* is a "link" button, and no Help event will occur. */
-
- switch( id )
- {
- case jokeTag:
- { /* Play the joke sound and return to the help server. */
- Handle soundHandle;
- short saveRefNum = CurResFile( );
- UseResFile( applicationFileRefNum );
- soundHandle = Get1Resource( soundListRsrc, rJokeSound );
- UseResFile( saveRefNum );
- if( soundHandle != nil )
- {
- SndPlay( nil, soundHandle, false );
- ReleaseResource( soundHandle );
- }
- DisplayHelp( 0, false );
- }
- break;
- default:
- /* This is some unknown help event. */
- ErrorAlert( "HELP EVENT!", id );
- break;
- }
-
- }
-
- #pragma segment Main
- pascal OSErr AppleEventHandler( AppleEvent *appleEventPtr, AppleEvent *replyEventPtr, long refCon )
- {
- #pragma unused( replyEventPtr, refCon )
- OSErr osErr = noErr;
- DescType descType;
- Size size;
- AEKeyword keyword;
-
- if( osErr == noErr )
- { /* Figure out which kind of event this is. */
- osErr = AEGetAttributePtr( appleEventPtr, keyEventIDAttr, typeWildCard, &descType, (Ptr) &keyword, sizeof( keyword ), &size );
- }
-
- if( osErr == noErr )
- {
- /* Your application has to support the Required suite of Apple events, because its */
- /* 'SIZE' resource tells Finder that it is high-level-event-aware. See Inside Macintosh */
- /* Volume VI for information on handling these events. */
- switch( keyword )
- {
- case kAEOpenApplication:
- break;
- case kAEOpenDocuments:
- case kAEPrintDocuments:
- break;
- case kAEQuitApplication:
- /* We can't call Terminate here. Let the main event loop do the terminating. */
- done = true;
- break;
- default:
- osErr = errAEEventNotHandled;
- break;
- }
- }
-
- return osErr;
-
- }
-
- /* initialize & terminate */
-
- #pragma segment Initialize
- Boolean Initialize( )
- {
-
- /* Initialize mac. */
- (void) SysEnvirons( curSysEnvVers, &mac );
-
- { /* Gestalt... */
- long response;
- helpMgrPresent = ( Gestalt( gestaltHelpMgrAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltHelpMgrPresent );
- appleEventsPresent = ( Gestalt( gestaltAppleEventsAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltAppleEventsPresent );
- launchControl = ( Gestalt( gestaltOSAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltLaunchControl );
- findFolderPresent = ( Gestalt( gestaltFindFolderAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltFindFolderPresent );
- aliasMgrPresent = ( Gestalt( gestaltAliasMgrAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltAliasMgrPresent );
- standardFile58 = ( Gestalt( gestaltStandardFileAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltStandardFile58 );
- hasFSSpecCalls = ( Gestalt( gestaltFSAttr, &response ) == noErr ) && BitTst( &response, 31 - gestaltHasFSSpecCalls );
- }
-
- /* Initialize wneIsImplemented. */
- wneIsImplemented = mac.machineType >= 0 && TrapAvailable( _WaitNextEvent, ToolTrap );
-
- /* Initialize inForeground. */
- inForeground = true;
-
- /* Initialize the relevant parts of System. */
- InitGraf( (Ptr) &qd.thePort );
- InitFonts( );
- InitWindows( );
- InitMenus( );
- InitDialogs( nil );
- InitCursor( );
-
- if( !appleEventsPresent )
- {
- ErrorMessage( iHoWSampleRequiresAppleEvents, 0 );
- return false;
- }
-
- if( !launchControl )
- {
- ErrorMessage( iHoWSampleRequiresProcessManager, 0 );
- return false;
- }
-
- if( !findFolderPresent )
- {
- ErrorMessage( iHoWSampleRequiresFolderManager, 0 );
- return false;
- }
-
- if( !aliasMgrPresent )
- {
- ErrorMessage( iHoWSampleRequiresAliasManager, 0 );
- return false;
- }
-
- if( !standardFile58 )
- {
- ErrorMessage( iHoWSampleRequiresEnhancedStandardFile, 0 );
- return false;
- }
-
- if( !hasFSSpecCalls )
- {
- ErrorMessage( iHoWSampleRequiresFSSpecCalls, 0 );
- return false;
- }
-
- if( !wneIsImplemented )
- {
- ErrorMessage( iHoWSampleRequiresWaitNextEvent, 0 );
- return false;
- }
-
- { /* Set up the menu bar. */
- SetMenuBar( GetNewMBar( rMenuBar ) );
- AddResMenu( GetMHandle( mApple ), 'DRVR' );
- if( helpMgrPresent )
- { /* If this isn't called before DrawMenuBar, it will fail later if SpeedyFinder7's Help menu removal option is on. */
- MenuHandle dummyMenuHandle;
- (void) HMGetHelpMenuHandle( &dummyMenuHandle );
- }
- DrawMenuBar( );
- }
-
- { /* Open the preferences file. */
- OSErr osErr;
- long preferencesFolderDirID;
- char preferencesFileName[ 256 ];
- FSSpec fsSpec;
- const Boolean resolveAliasChains = true;
- Boolean targetIsFolder;
- Boolean wasAliased;
- osErr = FindFolder( kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &preferencesFolderVRefNum, &preferencesFolderDirID );
- if( osErr != noErr )
- {
- ErrorMessage( iCantFindPreferencesFolder, osErr );
- return false;
- }
- osErr = FSMakeFSSpec( preferencesFolderVRefNum, preferencesFolderDirID, (Str255) c2pstr( GetPreloadString( iHoWSamplePreferencesFileName, preferencesFileName ) ), &fsSpec );
- if( osErr != noErr && osErr != fnfErr )
- {
- ErrorMessage( iCantAccessPreferencesFile, osErr );
- return false;
- }
- osErr = ResolveAliasFile( &fsSpec, resolveAliasChains, &targetIsFolder, &wasAliased );
- if( ( osErr != noErr && osErr != fnfErr ) || targetIsFolder )
- {
- ErrorMessage( iCantResolvePreferencesFileAlias, osErr );
- return false;
- }
- osErr = FSpCreate( &fsSpec, tHoWSample, tHoWSamplePreferences, smSystemScript );
- if( osErr != noErr && osErr != dupFNErr && osErr != wPrErr )
- {
- ErrorMessage( iCantCreatePreferencesFile, osErr );
- return false;
- }
- FSpCreateResFile( &fsSpec, tHoWSample, tHoWSamplePreferences, smSystemScript );
- applicationFileRefNum = CurResFile( );
- /* It is necessary to check volume lock status because the file system will let you */
- /* open a file for write as long as the file itself is not locked. */
- if( preferencesFileUnwritable = IsVolumeLocked( preferencesFolderVRefNum ) || ( preferencesFileRefNum = FSpOpenResFile( &fsSpec, fsRdPerm | fsWrPerm ) ) == -1 )
- {
- if( ( preferencesFileRefNum = FSpOpenResFile( &fsSpec, fsRdPerm ) ) == -1 )
- WarningMessage( iPreferencesFileUnreadable );
- else
- WarningMessage( iPreferencesFileUnwritable );
- }
- UseResFile( applicationFileRefNum );
- }
-
- { /* Register with Help on Wheels for help service using help file alias resource */
- /* in preferences or application file. The alias resource comes from the */
- /* “HoWSample Help alias” Finder alias file, so it contains relative alias information. */
- /* This information is relative to the Finder alias file itself, which was created in */
- /* the same directory as the help file. HoWFindHelpFile expects the alias resource */
- /* to be relative to the application file. */
- /* So, as long as the help file and the application file are in the same directory, */
- /* this information can be used to resolve the alias with a fast alias search. */
- /* If the fast search fails, HoWFindHelpFile will do an exhaustive search of all */
- /* volumes, but if the exhaustive search fails once, the preferences file's alias */
- /* resource is marked to prevent repeating the failed search. */
- /* Once successfully resolved, the non-relative information in the alias record */
- /* (volume, file ID) will keep track of the help file. */
- FSSpec helpFileFSSpec;
- OSErr osErr = HoWFindHelpFile( preferencesFileRefNum, applicationFileRefNum, rHelpFileAlias, &helpFileFSSpec );
- helpServerPresent = false;
- if( osErr == noErr )
- { /* We don't start the server right away. The server will start when the user */
- /* asks for help. If we did ask to start the server right away, HoWRegister */
- /* would return noServerApplErr if the help server application cannot be found. */
- /* noServerApplErr is not fatal; the client is registered anyway, and a non-casual */
- /* HoWDisplay call will cause the client engine to offer the user a TeachText */
- /* version of the help file. The same thing could happen to us when we call */
- /* HoWDisplay, but we can't tell that it's happening. The 'Lang' resource gives */
- /* the language code for which this application has been localized. By preference, */
- /* if it can find support in the help file, the help server will use the current */
- /* script's current language, or its own language, before using this default language. */
- LangCode **clientLanguageHandle = (LangCode **) GetIndResource( 'Lang', 1 );
- LangCode clientLanguage = ( clientLanguageHandle != nil ) ? **clientLanguageHandle : langEnglish;
- osErr = HoWRegister( &helpFileFSSpec, helpFileVersion, clientLanguage, false, (HoWHandlerProcPtr) HelpEventHandler );
- switch( osErr )
- {
- case noErr:
- helpServerPresent = true;
- break;
- case wrongVersionErr:
- WarningMessage( iHelpFileWrongVersion );
- break;
- default:
- WarningMessage( iHoWRegisterFailed );
- break;
- }
- UnloadSeg( (Ptr) HoWRegister );
- }
- /* If osErr != noErr, we don't complain. For example, a return code of fnfErr from */
- /* HoWFindHelpFile may just mean that the user has trashed the help file. */
- }
-
- if( helpMgrPresent )
- { /* Add the "HoWSample Help" item and subsidiary items to the Help menu. */
- MenuHandle helpMenuHandle;
- OSErr osErr = HMGetHelpMenuHandle( &helpMenuHandle );
- if( osErr == noErr && helpMenuHandle != nil )
- {
- char itemString[ 256 ];
- systemHelpItemCount = CountMItems( helpMenuHandle );
- appendmenu( helpMenuHandle, GetPreloadString( iHoWSampleHelpFileName, itemString ) );
- if( !helpServerPresent )
- DisableItem( helpMenuHandle, CountMItems( helpMenuHandle ) );
- AppendMenu( helpMenuHandle, "\p(-" );
- appendmenu( helpMenuHandle, GetPreloadString( iDialogHelpString, itemString ) );
- if( !helpServerPresent )
- DisableItem( helpMenuHandle, CountMItems( helpMenuHandle ) );
- appendmenu( helpMenuHandle, GetPreloadString( iMenuHelpString, itemString ) );
- if( !helpServerPresent )
- DisableItem( helpMenuHandle, CountMItems( helpMenuHandle ) );
- }
- }
-
- { /* Install the handler for our Apple events. */
- (void) AEInstallEventHandler( kCoreEventClass, typeWildCard, (EventHandlerProcPtr) AppleEventHandler, 0, false );
- }
-
- { /* Initialize helpCommandChar. */
- char string[ 256 ];
- helpCommandChar = *GetPreloadString( iHelpCommandChar, string );
- }
-
- return true;
-
- }
-
- #pragma segment Main
- void Terminate( )
- {
-
- /* Deregister with Help on Wheels. */
- (void) HoWDeregister( );
-
- ExitToShell( );
-
- }
-
- /* user interaction and alerts */
-
- #pragma segment Main
- OSErr InteractOrTimeOut( short timeOut )
- { /* Use the application's icon family as the notification icon family. */
- OSErr osErr;
- NMRec nmRec;
-
- nmRec.qType = nmType;
- nmRec.nmMark = 1;
- (void) GetIconSuite( &nmRec.nmIcon, rPrincipalIconFamily, svAllAvailableD );
- if( nmRec.nmIcon != nil )
- HNoPurge( nmRec.nmIcon );
- nmRec.nmSound = nil;
- nmRec.nmStr = nil;
- nmRec.nmResp = nil;
-
- /* We can call AEInteractWithUser whether or not we are in an Apple event context. */
- osErr = AEInteractWithUser( timeOut, &nmRec, nil );
-
- if( nmRec.nmIcon != nil )
- HPurge( nmRec.nmIcon );
- (void) DisposeIconSuite( nmRec.nmIcon, true );
-
- return osErr;
-
- }
-
- #pragma segment Main
- void InfoAlert( const char *string )
- {
-
- (void) InteractOrTimeOut( kNoTimeOut );
-
- paramtext( string, nil, nil, nil );
- (void) NoteAlert( rGeneralAlert, nil );
-
- }
-
- #pragma segment Main
- void WarningAlert( const char *string )
- {
-
- (void) InteractOrTimeOut( kNoTimeOut );
-
- paramtext( string, nil, nil, nil );
- (void) CautionAlert( rGeneralAlert, nil );
-
- }
-
- #pragma segment Main
- void ErrorAlert( const char *string, long code )
- {
- char errorString[ 256 ];
-
- (void) InteractOrTimeOut( kNoTimeOut );
-
- SysBeep( 0 );
- if( code == 0 )
- strcpy( errorString, string );
- else if( code == memFullErr )
- sprintf( errorString, "%s [out of memory]", string );
- else
- sprintf( errorString, "%s [%ld]", string, code );
- paramtext( errorString, nil, nil, nil );
- (void) StopAlert( rGeneralAlert, nil );
-
- }
-
- /* 'STR#' utilities */
-
- #pragma segment Main
- char *GetMessage( short messageID, char *message )
- {
-
- if( messageID <= 0 )
- {
- char genericErrorMessage[ 256 ];
- getindstring( genericErrorMessage, rMessages, iGenericErrorMessage );
- if( ResError( ) == noErr )
- sprintf( message, genericErrorMessage, messageID );
- }
- else
- getindstring( message, rMessages, messageID );
-
- if( ResError( ) != noErr )
- sprintf( message, "Internal error %d has occurred.", messageID );
-
- return message;
-
- }
-
- #pragma segment Main
- void WarningMessage( short warningID )
- {
- char warningMessage[ 256 ];
-
- WarningAlert( GetMessage( warningID, warningMessage ) );
-
- }
-
- #pragma segment Main
- void ErrorMessage( short errorID, long code )
- {
- char errorMessage[ 256 ];
-
- ErrorAlert( GetMessage( errorID, errorMessage ), code );
-
- }
-
- #pragma segment Main
- char *GetPreloadString( short stringID, char *string )
- {
-
- getindstring( string, rPreloadStrings, stringID );
-
- if( ResError( ) != noErr )
- {
- ErrorMessage( iCantGetPreloadString, ResError( ) );
- strcpy( string, "ERROR" );
- }
-
- return string;
-
- }
-
- /* dos */
-
- #pragma segment Main
- pascal Boolean AboutModalDialogFilter( DialogPtr dialog, EventRecord *theEvent, short *itemHit )
- {
-
- /* This filter is needed because without it, the about alert doesn't get highlighted. */
- /* We force highlighting on the first event. */
- if( !GetWRefCon( (WindowPtr) dialog ) )
- {
- SetWRefCon( (WindowPtr) dialog, true );
- HiliteWindow( (WindowPtr) dialog, true );
- SetDialogDefaultItem( dialog, ok );
- SetDialogCancelItem( dialog, ok );
- SetDialogTracksCursor( dialog, false );
- }
-
- return GeneralModalDialogFilter( dialog, theEvent, itemHit );
-
- }
-
- #pragma segment Main
- void DoAbout( void )
- {
- Boolean balloonState = helpMgrPresent && HMGetBalloons( );
-
- if( helpMgrPresent )
- HMSetBalloons( !balloonState );
-
- topicTag = rAboutAlert * cTagSpacing;
- (void) Alert( rAboutAlert, (ModalFilterProcPtr) AboutModalDialogFilter );
-
- if( helpMgrPresent )
- HMSetBalloons( balloonState );
-
- }
-
- #pragma segment Main
- void DoMenuCommand( long menuResult, Boolean option )
- {
- #pragma unused( option )
- short menuID = HiWord( menuResult );
- short menuItem = LoWord( menuResult );
- Str255 daName;
- short menuTopicTag = menuID * cTagSpacing + menuItem;
-
- switch( menuID )
- {
- case mApple:
- switch( menuItem )
- {
- case iAbout:
- /* This is an example of a casual help display. */
- /* A casual display is effective only if the server is started and running in */
- /* the background, with the "follow" option in effect, and already displaying */
- /* this client's help file. */
- DisplayHelp( menuTopicTag, true );
- DoAbout( );
- break;
- default:
- GetItem( GetMHandle( mApple ), menuItem, daName );
- (void) OpenDeskAcc( daName );
- break;
- }
- break;
- case mFile:
- switch( menuItem )
- {
- case iQuit:
- DisplayHelp( menuTopicTag, true );
- done = true;
- break;
- }
- break;
- case mEdit:
- DisplayHelp( menuTopicTag, true );
- (void) SystemEdit( menuItem - 1 );
- break;
- case mDemo:
- switch( menuItem )
- {
- case iDoNothing:
- DisplayHelp( menuTopicTag, true );
- DoNothingDialog( );
- UnloadSeg( (Ptr) DoNothingDialog );
- break;
- }
- break;
- case kHMHelpMenuID:
- /* This is a non-casual help display. The user directly asked for help. */
- switch( menuItem - systemHelpItemCount )
- {
- case iHoWSampleHelp:
- DisplayHelp( topicTag, false );
- break;
- case iDialogHelp:
- DisplayHelp( dialogTag, false );
- break;
- case iMenuHelp:
- DisplayHelp( menuTag, false );
- break;
- }
- }
-
- HiliteMenu( 0 );
-
- }
-
- #pragma segment Main
- void DoContentClick( WindowPtr window, EventRecord *event )
- {
- #pragma unused( event )
-
- if( IsAppWindow( window ) )
- {
- }
-
- }
-
- #pragma segment Main
- void DoKeyDown( EventRecord *event )
- {
- unsigned char characterCode = event->message & charCodeMask;
-
- switch( characterCode )
- {
- case 0x05: /* Help */
- /* This is a non-casual help display. The user directly asked for help. */
- DisplayHelp( topicTag, false );
- break;
- }
-
- }
-
- #pragma segment Main
- void DoUpdate( WindowPtr window )
- {
-
- if( IsAppWindow( window ) )
- {
- BeginUpdate( window );
- /* Do update processing here. */
- EndUpdate( window );
- }
-
- }
-
- #pragma segment Main
- void DoActivate( )
- {
-
- /* Set cursor to arrow shape. */
- SetCursor( &qd.arrow );
-
- }
-
- #pragma segment Main
- void DoDeactivate( )
- {
-
- }
-
- /* event handlers */
-
- #pragma segment Main
- void HandleMouseDownEvent( EventRecord *pEvent )
- {
- WindowPtr window;
- short part = FindWindow( pEvent->where, &window );
- Boolean option = pEvent->modifiers & optionKey || false;
-
- switch( part )
- {
- case inMenuBar:
- AdjustMenus( option );
- DoMenuCommand( MenuSelect( pEvent->where ), option );
- break;
- case inSysWindow:
- SystemClick( pEvent, window );
- break;
- case inContent:
- DoContentClick( window, pEvent );
- break;
- }
-
- }
-
- #pragma segment Main
- void HandleKeyDownEvent( EventRecord *pEvent )
- {
- char characterCode = pEvent->message & charCodeMask;
- Boolean option = pEvent->modifiers & optionKey || false;
-
- if( characterCode == helpCommandChar && pEvent->modifiers & cmdKey )
- { /* Map Command-<helpCommandChar> to the Help key. */
- pEvent->modifiers &= ~cmdKey;
- pEvent->message &= ~charCodeMask;
- pEvent->message |= 0x05;
- }
-
- if( pEvent->modifiers & cmdKey )
- {
- if( pEvent->what == keyDown )
- {
- AdjustMenus( option );
- DoMenuCommand( MenuKey( characterCode ), option );
- }
- }
- else DoKeyDown( pEvent );
-
- }
-
- #pragma segment Main
- void HandleUpdateEvent( EventRecord *pEvent )
- {
-
- DoUpdate( (WindowPtr) pEvent->message );
-
- }
-
- #pragma segment Main
- void HandleActivateEvent( EventRecord *pEvent )
- {
-
- if( pEvent->modifiers & activeFlag )
- {
- DoActivate( );
- }
- else
- {
- DoDeactivate( );
- }
-
- }
-
- #pragma segment Main
- void HandleOSEvent( EventRecord *pEvent )
- {
-
- switch( pEvent->message & osEvtMessageMask )
- {
- case suspendResumeMessage << 24:
- if( pEvent->message & resumeFlag )
- {
- inForeground = true;
- DoActivate( );
- }
- else
- {
- inForeground = false;
- DoDeactivate( );
- }
- break;
- }
-
- }
-
- #pragma segment Main
- void HandleHighLevelEvent( EventRecord *pEvent )
- {
-
- switch( pEvent->message )
- {
- /* Any application-defined high-level event processing goes here. */
- default:
- (void) AEProcessAppleEvent( pEvent );
- UnloadSeg( (Ptr) HoWRegister ); /* in case this was a HoW Apple event */
- break;
- }
-
- }
-
- /* event loop */
-
- #pragma segment Main
- void EventLoop( )
- {
- EventRecord myEvent;
-
- FlushEvents( everyEvent, 0 );
-
- while( !done )
- {
- topicTag = 0;
- if( WaitNextEvent( everyEvent, &myEvent, sleepTicks, nil ) )
- {
- switch( myEvent.what )
- {
- case mouseDown:
- HandleMouseDownEvent( &myEvent );
- break;
- case keyDown:
- HandleKeyDownEvent( &myEvent );
- break;
- case updateEvt:
- HandleUpdateEvent( &myEvent );
- break;
- case osEvt:
- HandleOSEvent( &myEvent );
- break;
- case kHighLevelEvent:
- HandleHighLevelEvent( &myEvent );
- break;
- }
- }
- else
- { /* idle */
- }
- }
-
- }
-
- /* main */
-
- #pragma segment Main
- void main( )
- {
- extern void _DataInit( );
-
- UnloadSeg( (Ptr) _DataInit ); /* note that _DataInit must not be in Main! */
-
- MaxApplZone( ); /* expand the heap so code segments load at the top */
-
- MoreMasters( );
- MoreMasters( );
-
- /* Initialize globals, System, and application items. */
- if( !Initialize( ) ) Terminate( );
-
- UnloadSeg( (Ptr) Initialize ); /* note that Initialize must not be in Main! */
-
- EventLoop( );
-
- Terminate( );
-
- }